//https://gitlab.com/mwiget/xdp-drop-test/-/tree/master
//https://stackoverflow.com/questions/64861121/ebpf-program-load-fails-without-verifier-log
#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#define SEC(NAME) __attribute__((section(NAME), used))
/*
struct bpf_map_def {
	unsigned int type;
	unsigned int key_size;
	unsigned int value_size;
	unsigned int max_entries;
	unsigned int map_flags;
	unsigned int id;
	unsigned int pinning;
	unsigned int inner_id;
	unsigned int inner_idx;
};
struct bpf_map_def SEC("maps") dummy_map = {
    .type        = BPF_MAP_TYPE_ARRAY,
    .key_size    = sizeof(int),
    .value_size  = sizeof(int),
    .max_entries = 1,
};*/
SEC("drop_icmp")
int drop_icmp_func(struct xdp_md *ctx) {
  //int key = 0;
  //int *v = (int*)bpf_map_lookup_elem(&dummy_map, &key);
  int ipsize = 0;

  void *data = (void *)(long)ctx->data;
  void *data_end = (void *)(long)ctx->data_end;

  struct ethhdr *eth = data;

  ipsize = sizeof(*eth);

  struct iphdr *ip = data + ipsize;
  ipsize += sizeof(struct iphdr);
  if (data + ipsize > data_end) {
    // not an ip packet, too short. Pass it on
    return XDP_PASS;
  }

  // technically, we should also check if it is an IP packet by
  // checking the ethernet header proto field ...
  if (ip->protocol == IPPROTO_ICMP) {
    return XDP_DROP;
  }

  return XDP_PASS;
}
char __license[] SEC("license") = "GPL";

